Mini rapport¶

Les difficultés consistaient surtout à se mettre d'accord au sein du groupe, notamment sur quelles variables (colonnes) garder et/ou supprimer par rapport à ce que l'on voulait faire. Il y aussi eu certaines difficultés à faire correspondre les valeurs du dataset avec les valeurs de création de carte ; ce qui peut être dû à notre manque de connaissance en Python, donc des méthodes utilisées pour générer les cartes correspondantes, il y a dû avoir des pertes d'informations entre ces processus. De plus, avec ces incertitudes, les recherches que nous voulions effectuer n'étaient pas toujours possibles, car les valeurs (donc les résultats) n'étaient pas exploitables, et/ou sortaient des résultats pas cohérents. Les résultats/tendances obtenu(s) n'étaient pas toujours faciles à expliquer, car beaucoup de facteurs qui peuvent nous être inconnus doivent entrer en jeu.

Contribution¶

Manon GOFFINET : 33% ; Kevin HERMAND : 33% ;  Joyce LAPILUS : 33%

1. Chargement des données¶

In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
#import chart_studio.plotly as py
import plotly.offline as pyo
pd.options.mode.chained_assignment = None  # default='warn'

from urllib.request import urlopen
import json
with urlopen('https://france-geojson.gregoiredavid.fr/repo/departements.geojson') as response:
    departement = json.load(response)

from urllib.request import urlopen
import json
with urlopen('https://france-geojson.gregoiredavid.fr/repo/regions.geojson') as response:
    region = json.load(response)

Lors de cette analyse, on se concentrera sur une comparaison des valeurs foncières récentes contre celle pré-Covid. On analysera donc principalement les datasets des valeurs foncières de 2019, l'année précédant la crise du Covid, et celles de 2022, l'année fraîchement terminée.

In [2]:
foncier2019 = pd.read_csv("Data/valeursfoncieres-2019.txt",low_memory=False, sep='|')
In [3]:
foncier2020 = pd.read_csv("Data/valeursfoncieres-2020.txt",low_memory=False, sep='|')
In [4]:
foncier2021 = pd.read_csv("Data/valeursfoncieres-2021.txt",low_memory=False, sep='|')
In [5]:
foncier2022 = pd.read_csv("Data/valeursfoncieres-2022.txt", low_memory=False, sep="|")
In [6]:
datasets = [foncier2019,foncier2020,foncier2021,foncier2022]

2. Nettoyage des données¶

Détection et suppression des valeurs manquantes/Suppression des doublons/Gestion des valeurs "extrêmes"¶

Après réflexion, plusieurs colonnes présentes dans le dataset initial ne nous servent pas dans l'analyse que nous voulons effectuer ; cette dernière se portant majoritairement sur le prix moyen du mètre carré d'un département d'une ville, comparaison entre différents type, appart, maison, geomap, différence entre ville, départements, régions,... On "nettoie" donc les datasets en supprimant les colonnes "inutiles", en supprimant les lignes contenant des valeurs nulle, puis en convertissant les données recueillies en type lisible et exploitable par le compilateur Python.

Nettoyage¶

In [7]:
# On parcourt les datasets présents dans la liste créée précédemment
for i in range(len(datasets)):
    df=datasets[i]
    
    # Suppression des colonnes "inutiles"
    df = df.drop(['Identifiant de document', '1 Articles CGI', 
                   '2 Articles CGI', '3 Articles CGI', '4 Articles CGI', 
                   '5 Articles CGI', 'Reference document', 'No disposition', 
                   'No voie', 'B/T/Q', 'Code voie', 'Prefixe de section', 
                   'Section', 'No plan', 'No Volume', '1er lot', 
                   'Surface Carrez du 1er lot', '2eme lot', 
                   'Surface Carrez du 2eme lot', '3eme lot', 
                   'Surface Carrez du 3eme lot', '4eme lot', 
                   'Surface Carrez du 4eme lot', '5eme lot', 
                   'Surface Carrez du 5eme lot', 'Code type local', 
                   'Identifiant local', 'Nature culture', 
                   'Nature culture speciale'], axis=1)

    # Suppression des lignes contenant des valeurs nulles (non exploitables)
    df = df.dropna()

    # Conversion des colonnes en leur type de données approprié
    df['Date mutation'] = pd.to_datetime(df['Date mutation'], format='%d/%m/%Y')
    df['Valeur fonciere'] = pd.to_numeric(df['Valeur fonciere'].str.replace(',', '.'))
    df['Surface reelle bati'] = df['Surface reelle bati'].astype('int')
    df['Nombre pieces principales'] = df['Nombre pieces principales'].astype('int')
    df['Surface terrain'] = df['Surface terrain'].astype('int')

    # Correction du format des codes postaux 
    df["Code postal"] = df["Code postal"].apply(lambda x: "0" + str(x).split('.')[0] if len(str(x).split('.')[0]) == 4 else str(x).split('.')[0])

    datasets[i] = df
In [8]:
# On déclare des variables pour stocker les DataFrames pour faciliter les interprétations suivantes
foncier2019 = datasets[0]
foncier2021 = datasets[1]
foncier2022 = datasets[2]
foncier2022 = datasets[3]
In [9]:
foncier2019
Out[9]:
Date mutation Nature mutation Valeur fonciere Type de voie Voie Code postal Commune Code departement Code commune Nombre de lots Type local Surface reelle bati Nombre pieces principales Surface terrain
3 2019-01-08 Vente 209000.0 RUE DES CHAMPAGNES 01160 PRIAY 01 314 0 Maison 90 4 940
4 2019-01-07 Vente 134900.0 LOT LE BIOLAY 01370 SAINT-ETIENNE-DU-BOIS 01 350 0 Maison 101 5 490
5 2019-01-03 Vente 192000.0 ALL DES LIBELLULES 01340 ATTIGNAT 01 24 0 Maison 88 4 708
6 2019-01-08 Vente 45000.0 RTE DU VIADUC 01250 CIZE 01 106 0 Maison 39 2 631
13 2019-01-07 Vente 116000.0 RTE DE MONTLEGER 01560 MANTENAY-MONTLIN 01 230 0 Maison 100 1 2103
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3625891 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Local industriel. commercial ou assimilé 16 0 470
3625892 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Dépendance 0 0 470
3625893 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Dépendance 0 0 470
3625894 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Dépendance 0 0 470
3625895 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Dépendance 0 0 470

842833 rows × 14 columns

In [10]:
foncier2022
Out[10]:
Date mutation Nature mutation Valeur fonciere Type de voie Voie Code postal Commune Code departement Code commune Nombre de lots Type local Surface reelle bati Nombre pieces principales Surface terrain
5 2022-01-06 Vente 255000.0 RTE DE POISATON 01560 MANTENAY-MONTLIN 01 230 0 Maison 108 5 649
8 2022-01-03 Vente 525000.0 PL DE LA CROIX BLANCHE 01390 SAINT-ANDRE-DE-CORCY 01 333 0 Local industriel. commercial ou assimilé 424 0 628
9 2022-01-03 Vente 525000.0 PL DE LA CROIX BLANCHE 01390 SAINT-ANDRE-DE-CORCY 01 333 0 Appartement 126 4 628
13 2022-01-03 Vente 140000.0 RUE DE BEAUGENCY 01000 BOURG-EN-BRESSE 01 53 0 Maison 100 4 796
21 2022-01-10 Vente 580000.0 RUE DES COMBES 01500 AMBRONAY 01 7 0 Dépendance 0 0 496
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3803693 2022-12-28 Vente 12281000.0 RUE AMELOT 75011 PARIS 11 75 111 0 Appartement 78 3 265
3803694 2022-12-28 Vente 12281000.0 RUE AMELOT 75011 PARIS 11 75 111 0 Appartement 17 1 265
3803695 2022-12-28 Vente 12281000.0 RUE AMELOT 75011 PARIS 11 75 111 0 Appartement 49 3 265
3803705 2022-12-30 Vente 3100000.0 AV DU DOC ARNOLD NETTER 75012 PARIS 12 75 112 0 Local industriel. commercial ou assimilé 709 0 258
3803723 2022-12-08 Vente 2600000.0 SQ DE MONTSOURIS 75014 PARIS 14 75 114 0 Maison 180 8 163

1023704 rows × 14 columns

Modification¶

In [11]:
foncier2022=foncier2022.dropna(axis=0,subset=['Valeur fonciere','Surface terrain'])
foncier2022=foncier2022[foncier2022['Surface terrain'] != 0]
In [12]:
#Pour les cartes :
foncier2022['Code departement'].astype(str)

def CodeRegion(codeDep):
    if codeDep=="01" or codeDep=="03" or codeDep=="07" or codeDep=="15" or codeDep=="26" or codeDep=="38" or codeDep=="42" or codeDep=="43" or codeDep=="63" or codeDep=="69" or codeDep=="73" or codeDep=="74":
        return "84"
    elif codeDep=="02" or codeDep=="59" or codeDep=="60" or codeDep=="62" or codeDep=="80":
        return "32"
    elif codeDep=="04" or codeDep=="05" or codeDep=="06" or codeDep=="13" or codeDep=="83" or codeDep=="84":
        return "93"
    elif codeDep=="08" or codeDep=="10" or codeDep=="51" or codeDep=="52" or codeDep=="54" or codeDep=="55" or codeDep=="57" or codeDep=="67" or codeDep=="68" or codeDep=="88":
        return "44"
    elif codeDep=="09" or codeDep=="11" or codeDep=="12" or codeDep=="30" or codeDep=="31" or codeDep=="32" or codeDep=="34" or codeDep=="46" or codeDep=="48" or codeDep=="65" or codeDep=="66" or codeDep=="81" or codeDep=="82":
        return "76"
    elif codeDep=="14" or codeDep=="27" or codeDep=="50" or codeDep=="61" or codeDep=="76" or codeDep=="14":
        return "28"
    elif codeDep=="16" or codeDep=="17" or codeDep=="17" or codeDep=="19" or codeDep=="23" or codeDep=="24" or codeDep=="33" or codeDep=="40" or codeDep=="47" or codeDep=="64" or codeDep=="79" or codeDep=="86" or codeDep=="87":
        return "75"
    elif codeDep=="18" or codeDep=="28" or codeDep=="36" or codeDep=="37" or codeDep=="41" or codeDep=="45":
        return "24"
    elif codeDep=="2A" or codeDep=="2B":
        return "94"
    elif codeDep=="21" or codeDep=="25" or codeDep=="39" or codeDep=="58" or codeDep=="70" or codeDep=="71" or codeDep=="89" or codeDep=="90":
        return "27"
    elif codeDep=="22" or codeDep=="29" or codeDep=="35" or codeDep=="56":
        return "53"
    elif codeDep=="44" or codeDep=="49" or codeDep=="53" or codeDep=="72" or codeDep=="85":
        return "52"
    elif codeDep=="75" or codeDep=="77" or codeDep=="78" or codeDep=="91" or codeDep=="92" or codeDep=="93" or codeDep=="94" or codeDep=="95":
        return "11"
    elif codeDep=="971":
        return "01"
    elif codeDep=="972":
        return "02"
    elif codeDep=="973":
        return "03"
    elif codeDep=="974":
        return "04"
    
    

foncier2022['Code région']=foncier2022['Code departement'].apply(CodeRegion)

3. Interprétation des données¶

Prix moyen du mètre carré d'un département d'une ville, comparaison entre différents type, appart, maison, geomap, différence entre ville, départements, régions,...

Graphiques de l'évolution des ventes entre 2019 et 2022¶

In [13]:
#EVOLUTION DU NB DE VENTES SELONS LES MOIS EN 2019
import matplotlib.pyplot as plt

# Ajouter une colonne 'Mois' au DataFrame
foncier2019['Mois'] = foncier2019['Date mutation'].dt.month

# Compter le nombre de ventes par mois
ventes_par_mois = foncier2019.groupby('Mois')['Date mutation'].count().reset_index()

# Créer un graphique d'évolution des ventes selon les mois
plt.figure(figsize=(10, 5))
plt.plot(ventes_par_mois['Mois'], ventes_par_mois['Date mutation'])
plt.xlabel('Mois')
plt.ylabel('Nombre de ventes')
plt.title("Évolution des ventes selon les mois en 2019")
plt.xticks(range(1, 13))
plt.grid()
plt.show()

Baisse des ventes en août, hausse des ventes juste avant les vacances d'été et celles de Noël ; ce qui est logique car les acheteurs ont plus de temps pour faire les démarches administratives, ces vacances étant les plus longues.

In [14]:
#EVOLUTION DU NB DE VENTES SELONS LES MOIS EN 2022
import matplotlib.pyplot as plt

# Ajouter une colonne 'Mois' au DataFrame
foncier2022['Mois'] = foncier2022['Date mutation'].dt.month

# Compter le nombre de ventes par mois
ventes_par_mois = foncier2022.groupby('Mois')['Date mutation'].count().reset_index()

# Créer un graphique d'évolution des ventes selon les mois
plt.figure(figsize=(10, 5))
plt.plot(ventes_par_mois['Mois'], ventes_par_mois['Date mutation'])
plt.xlabel('Mois')
plt.ylabel('Nombre de ventes')
plt.title("Évolution des ventes selon les mois en 2022")
plt.xticks(range(1, 13))
plt.grid()
plt.show()

On remarque un pic des ventes aux mois de juin et juillet, juste avant les vacances d'été. Les baisses suivantes peuvent être expliquées par les dégâts de la guerre en Ukraine, qui a débuté en février 2022 ; ce qui a causé sur le long terme une augmentation du prix de l'immobilier couplée aux débuts de l'inflation. La baisse des ventes entre septembre et novembre peut notamment être expliquée par l'augmentation des prix du gaz (qui impacte également ceux de l'électricité), qui aurait pu dissuader les nouveaux acheteurs dans leur aventure.

In [15]:
#EVOLUTION DES VENTES SELONS LES MOIS 2019-2022
import matplotlib.pyplot as plt

def ventes_par_mois(df, year):
    df['Date mutation'] = pd.to_datetime(df['Date mutation'], format='%d/%m/%Y') #convertit au cas où précédent pas excécuté
    df['Mois'] = df['Date mutation'].dt.month #récupère uniquement le mois
    ventes_par_mois = df.groupby('Mois')['Date mutation'].count().reset_index() #regroupe par mois et compte le nb d'élément (vente)
    ventes_par_mois.columns = ['Mois', f'Ventes {year}']
    return ventes_par_mois

# Préparer les données et extraire le nombre de ventes par mois pour chaque année
ventes_par_mois_2019 = ventes_par_mois(foncier2019, 2019)
ventes_par_mois_2020 = ventes_par_mois(foncier2020, 2020)
ventes_par_mois_2021 = ventes_par_mois(foncier2021, 2021)
ventes_par_mois_2022 = ventes_par_mois(foncier2022, 2022)

# Tracer les courbes sur le même graphique
plt.figure(figsize=(10, 5))
plt.plot(ventes_par_mois_2019['Mois'], ventes_par_mois_2019['Ventes 2019'], label='2019')
plt.plot(ventes_par_mois_2020['Mois'], ventes_par_mois_2020['Ventes 2020'], label='2020')
plt.plot(ventes_par_mois_2021['Mois'], ventes_par_mois_2021['Ventes 2021'], label='2021')
plt.plot(ventes_par_mois_2022['Mois'], ventes_par_mois_2022['Ventes 2022'], label='2022')

plt.xlabel('Mois')
plt.ylabel('Nombre de ventes')
plt.title("Évolution des ventes selon les mois (2019-2022)")
plt.xticks(range(1, 13))
plt.grid()
plt.legend()
plt.show()

Pour l'année 2020, on peut voir une certaine incohérence dans la courbe représentative de l'année 2020, donc on ne l'utilisera pas lors de nos prochaines analyses. On peut constater une baisse significative en 2020 lors de la période de confinement

Globalement, on observe toujours une hausse des ventes aux mois de juin/juillet et décembre.

Comparaison du prix moyen entre 2019 et 2022¶

In [16]:
foncier2019=foncier2019.dropna(axis=1,thresh=500000)
foncier2019=foncier2019.drop_duplicates()

foncier2019['Code departement'].astype(str)
foncier2019['Code région']=foncier2019['Code departement'].apply(CodeRegion)

foncier2019
Out[16]:
Date mutation Nature mutation Valeur fonciere Type de voie Voie Code postal Commune Code departement Code commune Nombre de lots Type local Surface reelle bati Nombre pieces principales Surface terrain Mois Code région
3 2019-01-08 Vente 209000.0 RUE DES CHAMPAGNES 01160 PRIAY 01 314 0 Maison 90 4 940 1 84
4 2019-01-07 Vente 134900.0 LOT LE BIOLAY 01370 SAINT-ETIENNE-DU-BOIS 01 350 0 Maison 101 5 490 1 84
5 2019-01-03 Vente 192000.0 ALL DES LIBELLULES 01340 ATTIGNAT 01 24 0 Maison 88 4 708 1 84
6 2019-01-08 Vente 45000.0 RTE DU VIADUC 01250 CIZE 01 106 0 Maison 39 2 631 1 84
13 2019-01-07 Vente 116000.0 RTE DE MONTLEGER 01560 MANTENAY-MONTLIN 01 230 0 Maison 100 1 2103 1 84
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3625883 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Appartement 32 2 470 12 11
3625884 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Appartement 52 2 470 12 11
3625885 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Appartement 110 4 470 12 11
3625886 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Dépendance 0 0 470 12 11
3625891 2019-12-05 Vente 17521000.0 QUAI DE BETHUNE 75004 PARIS 04 75 104 0 Local industriel. commercial ou assimilé 16 0 470 12 11

729116 rows × 16 columns

In [17]:
prix_moyen_2019 = foncier2019['Valeur fonciere'].mean()
prix_moyen_2022 = foncier2022['Valeur fonciere'].mean()
diff_prix_moyen = prix_moyen_2022 - prix_moyen_2019
diff_prix_moyen
Out[17]:
235822.34181090002
In [18]:
labels = ['2019', '2022']
values = [prix_moyen_2019, prix_moyen_2022]

fig = px.bar(x=labels, y=values, labels={'x':'Année', 'y':'Prix moyen'}, title='Comparaison du prix moyen')
fig.show()

On constate une hausse du prix moyen des valeurs foncières en 2022 comparé à 2019, environ égale à 235 800 €. Ce qui est logique vu l'augmentation des prix de l'immobilier dû notamment à la crise du Covid.

In [19]:
# VALEUR FONCIERE MOYENNE PAR DEPARTEMENT
# Calcul de la valeur foncière moyenne par departement
foncier2022['Valeur fonciere']=foncier2022['Valeur fonciere'].replace(',','.',regex=True).astype(float)
d=pd.DataFrame(foncier2022.groupby(foncier2022["Code departement"]),foncier2022.groupby(foncier2022["Code departement"]).mean()["Valeur fonciere"])

dep_vf=d.reset_index()
dep_vf=dep_vf.rename(columns={0 : "Département"})
dep_vf=dep_vf.drop(columns=[1])

dep_vf.sort_values(by=['Valeur fonciere'], inplace=True, ascending=False)

dep_vf=dep_vf.reset_index()


#Affichage de la carte
fig = px.choropleth_mapbox(dep_vf, geojson=departement, locations='Département', color='Valeur fonciere',
                           color_continuous_scale="Viridis",
                           range_color=(0,1000000),
                           mapbox_style='carto-positron',
                           featureidkey="properties.code",
                           zoom=4,
                           center={'lat': 47, 'lon': 2},
                           opacity=0.8,)

pyo.iplot(fig,filename='jupyter-Valeur fonciere en france')

On note que l'immobilier est beaucoup plus cher à Paris, aux alentours de Paris et au sein des autres métropoles françaises, telles que Bordeaux, Lyon, etc. Notamment les département côtiers. On peut expliquer ceci par l'intérêt professionnel et/ou touristiques. Egalement par la densité de population de ces départements.

Répartition des ventes en France¶

Nombre de ventes par département¶

In [20]:
# Groupement des ventes par département
ventes_par_departement_2019 = foncier2019.groupby("Code departement").size().reset_index(name="Nombre de ventes")

fig = px.choropleth_mapbox(ventes_par_departement_2019, geojson=departement,
    locations="Code departement",
    color="Nombre de ventes",
    color_continuous_scale="Viridis",
    mapbox_style="carto-positron",
    featureidkey="properties.code",
    center={"lat": 46.603354, "lon": 1.888334},
    zoom=4,
    opacity=0.7,
    labels={"Nombre de ventes": "Nombre de ventes"})

fig.update_layout(title="Répartition des ventes en France en 2019")
fig.show()
In [21]:
# Groupement des ventes par département
ventes_par_departement_2022 = foncier2022.groupby("Code departement").size().reset_index(name="Nombre de ventes")

fig = px.choropleth_mapbox(ventes_par_departement_2022, geojson=departement,
    locations="Code departement",
    color="Nombre de ventes",
    color_continuous_scale="Viridis",
    mapbox_style="carto-positron",
    featureidkey="properties.code",
    center={"lat": 46.603354, "lon": 1.888334},
    zoom=4,
    opacity=0.7,
    labels={"Nombre de ventes": "Nombre de ventes"})

fig.update_layout(title="Répartition des ventes en France en 2022")
fig.show()

Nombre de ventes en ile de France¶

In [22]:
# Filtrer les données pour l'Île-de-France uniquement
idf_data_2019 = foncier2019[foncier2019['Code région']=='11']
idf_data_2022 = foncier2022[foncier2022['Code région']=='11']
In [23]:
# Répartition géographique des ventes en Île-de-France en 2019
ventes_departement_2019 = idf_data_2019['Code departement'].value_counts()

fig = px.choropleth(ventes_departement_2019, geojson=departement, locations=ventes_departement_2019.index,
                    color=ventes_departement_2019.values, featureidkey='properties.code',
                    projection="mercator", color_continuous_scale="Viridis",
                    labels={'color': 'Nombre de ventes'},
                    title='Répartition géographique des ventes en Île-de-France en 2019')
fig.update_geos(fitbounds="locations", visible=False)
fig.show()
In [24]:
# Répartition géographique des ventes en Île-de-France en 2022
ventes_departement_2022 = idf_data_2022['Code departement'].value_counts()

fig = px.choropleth(ventes_departement_2022, geojson=departement, locations=ventes_departement_2022.index,
                    color=ventes_departement_2022.values, featureidkey='properties.code',
                    projection="mercator", color_continuous_scale="Viridis",
                    labels={'color': 'Nombre de ventes'},
                    title='Répartition géographique des ventes en Île-de-France en 2022')
fig.update_geos(fitbounds="locations", visible=False)
fig.show()

Pas trop de changements entre 2019 et 2022. En liant ces données avec la carte de la répartition de la valeur foncière par départements, on remarque que la Seine-et-Marne (77) est le département le moins cher, il est donc logique que les acheteurs se tournent vers ce département pour leurs achats ; ce qui explique le nombre de ventes important. Notamment, ce département est celui avec le plus de surface habitable. Au contraire, Paris est surpeuplé et beaucoup plus cher, d'où le petit nombre de ventes.

Etude sur le prix du m²¶

Par département¶

En gardant les valeurs aberrantes¶

In [25]:
#PRIX MOYEN DU PRIX DU m² PAR DEPARTEMENT 

# Filtrer les données pour ne conserver que les ventes
ventes = foncier2022[foncier2022['Nature mutation'] == 'Vente']

# Créer une nouvelle colonne 'Prix par mètre carré'
ventes['Prix par mètre carré'] = ventes['Valeur fonciere'] / ventes['Surface terrain']

# Grouper les données par département
prix_moyen_par_departement = ventes.groupby('Code departement')['Prix par mètre carré'].mean().reset_index()

# Afficher les 10 premières lignes du DataFrame résultant
prix_moyen_par_departement.sort_values(by=['Prix par mètre carré'], inplace=True, ascending=False)
print(prix_moyen_par_departement.head(10))



# Calculer la moyenne nationale du prix par mètre carré
moyenne_nationale = ventes['Prix par mètre carré'].mean()

print("Moyenne nationale du prix du m² en France en 2022 : {:.2f} €".format(moyenne_nationale))
   Code departement  Prix par mètre carré
20               22          86587.064544
72               75          35064.133525
89               92          21011.289906
5                06           4794.246517
91               94           3737.252948
90               93           3563.985062
33               33           3339.630454
75               78           2900.221814
96              974           2657.044050
71               74           2637.764006
Moyenne nationale du prix du m² en France en 2022 : 3014.42 €
In [26]:
labels = prix_moyen_par_departement["Code departement"]
values = prix_moyen_par_departement["Prix par mètre carré"]

fig = px.bar(x=labels, y=values, labels={'x':'Département', 'y':'Prix au m²'}, title='Comparaison du prix du m²')
fig.show()

Après la suppression des valeurs aberrantes¶

In [27]:
#PRIX MOYEN DU PRIX DU m² PAR DEPARTEMENT APRES SUPPRESSION DES VALEURS ABERRANTES.

import numpy as np

# Filtrer les données pour ne conserver que les ventes
ventes = foncier2022[foncier2022['Nature mutation'] == 'Vente']

# Définir une fonction pour supprimer les valeurs aberrantes dans un DataFrame
def remove_outliers(df):
    Q1 = df['Prix par mètre carré'].quantile(0.25)
    Q3 = df['Prix par mètre carré'].quantile(0.75)
    IQR = Q3 - Q1
    df_out = df[~((df['Prix par mètre carré'] < (Q1 - 0.9 * IQR)) | (df['Prix par mètre carré'] > (Q3 + 0.9 * IQR)))]
    return df_out

# Créer une nouvelle colonne 'Prix par mètre carré'
ventes['Prix par mètre carré'] = ventes['Valeur fonciere'] / ventes['Surface terrain']

# Supprimer les valeurs aberrantes pour chaque département
ventes = ventes.groupby('Code departement').apply(remove_outliers).reset_index(drop=True)

# Grouper les données par département
prix_moyen_par_departement = ventes.groupby('Code departement')['Prix par mètre carré'].mean().reset_index()

# Afficher les 10 premières lignes du DataFrame résultant
prix_moyen_par_departement.sort_values(by=['Prix par mètre carré'], inplace=True, ascending=False)
print(prix_moyen_par_departement.head(10))

# Calculer la moyenne nationale du prix par mètre carré
moyenne_nationale = ventes['Prix par mètre carré'].mean()

print("Moyenne nationale du prix du m² en France en 2022 : {:.2f} €".format(moyenne_nationale))
   Code departement  Prix par mètre carré
72               75          25641.717329
20               22          24664.868317
89               92           4669.481322
91               94           1853.638001
90               93           1841.705299
5                06           1468.571020
75               78           1173.387456
4                05           1149.530783
12               13           1115.267005
92               95           1033.769090
Moyenne nationale du prix du m² en France en 2022 : 1156.94 €
In [28]:
labels = prix_moyen_par_departement["Code departement"]
values = prix_moyen_par_departement["Prix par mètre carré"]

fig = px.bar(x=labels, y=values, labels={'x':'Département', 'y':'Prix au m²'}, title='Comparaison du prix du m²')
fig.show()
In [29]:
ventes["Prix par mètre carré"].corr(ventes["Valeur fonciere"])
Out[29]:
0.6377322715870658

Le département de Paris et sa banlieue (92, 94, etc.) possède le m² le plus cher ; ce qui peut justifier le prix plus important de la valeur foncière dans ces mêmes départements. En effet, on observe une corrélation assez proche de 1 entre le prix par m² et la valeur foncière, ce qui appuie notre raisonnement.

Moyenne nationale du prix du m²¶

In [30]:
#Moyenne nationale du prix du m² en France en 2022 (après filtrage des valeurs aberrantes)

# Filtrer les données pour ne conserver que les ventes et créer une copie explicite
ventes = foncier2022[foncier2022['Nature mutation'] == 'Vente'].copy()

# Calculer la surface totale en utilisant la colonne 'Surface réelle bati'
ventes['Surface totale'] = ventes['Surface reelle bati']

# Filtrer les données pour éliminer les lignes où la surface totale est égale à zéro ou très proche de zéro
ventes = ventes[ventes['Surface totale'] > 0.0]

# Créer une nouvelle colonne 'Prix par mètre carré'
ventes['Prix par mètre carré'] = ventes['Valeur fonciere'] / ventes['Surface totale']

# Calculer le premier et troisième quartile (Q1 et Q3) ainsi que l'IQR
Q1 = ventes['Prix par mètre carré'].quantile(0.25)
Q3 = ventes['Prix par mètre carré'].quantile(0.75)
IQR = Q3 - Q1

# Filtrer les données pour éliminer les valeurs aberrantes en utilisant l'IQR
ventes_iqr = ventes[(ventes['Prix par mètre carré'] >= Q1 - 1.5 * IQR) & (ventes['Prix par mètre carré'] <= Q3 + 1.5 * IQR)]

# Calculer la moyenne nationale du prix par mètre carré pour les ventes filtrées
moyenne_nationale_filtree = ventes_iqr['Prix par mètre carré'].mean()

print("Moyenne nationale du prix du m² en France en 2022 (après filtrage des valeurs aberrantes) : {:.2f} €".format(moyenne_nationale_filtree))

import matplotlib.pyplot as plt

# Créer un diagramme en boîte à moustaches du prix par mètre carré
plt.figure(figsize=(10, 5))
plt.boxplot(ventes_iqr['Prix par mètre carré'])
plt.ylabel('Prix par mètre carré (€)')
plt.title('Diagramme en boîte à moustaches du prix par mètre carré en France en 2022 (après filtrage des valeurs aberrantes)')
plt.show()
Moyenne nationale du prix du m² en France en 2022 (après filtrage des valeurs aberrantes) : 2641.68 €

Etude sur les types de biens¶

In [31]:
types_biens_2019 = foncier2019['Type local'].value_counts(normalize=True)*100
types_biens_2022 = foncier2022['Type local'].value_counts(normalize=True)*100
In [32]:
fig = px.pie(types_biens_2019, values=types_biens_2019.values, names=types_biens_2019.index, title='Types de biens en 2019')
fig.show()
In [33]:
fig = px.pie(types_biens_2022, values=types_biens_2022.values, names=types_biens_2022.index, title='Types de biens en 2022')
fig.show()

On observe une augmentation du pourcentage d'achats des dépendances ; cela peut s'expliquer par le fait que beaucoup de personnes partent en voyage et ont donc besoin de stocker leurs biens pour une longue/courte durée. Egalement, une sorte d'exode rurale a eu lieu suite au Covid, donc les gens avaient besoin de stockage notamment pour leur moyen de locomotion.

Etude sur la surface¶

In [34]:
df_surface=ventes
df_surface['Surface terrain'].corr(df_surface['Surface reelle bati'])
Out[34]:
0.09905073005584472

La corrélation entre la surface terrain et la surface construite est inexistante comme on peut le voir.

Surface et nombres de pièces¶

In [35]:
df_nb_piece=df_surface.groupby(['Nombre pieces principales']).mean()
df_nb_piece=df_nb_piece.reset_index()
df_nb_piece
Out[35]:
Nombre pieces principales Valeur fonciere Code commune Nombre de lots Surface reelle bati Surface terrain Mois Surface totale Prix par mètre carré
0 0 3.157620e+06 215.407445 0.001596 648.162158 2797.968975 6.232576 648.162158 38857.587331
1 1 1.796825e+06 209.312223 0.011837 31.565816 1093.074588 6.140166 31.565816 76666.029031
2 2 1.734526e+06 213.038579 0.003416 50.487333 823.189027 6.153459 50.487333 38791.997764
3 3 1.582767e+06 219.835895 0.003593 73.092725 801.940117 6.124982 73.092725 24840.760629
4 4 9.009775e+05 225.589208 0.003681 95.536633 760.210042 6.133475 95.536633 10936.155989
5 5 5.285683e+05 236.009041 0.003571 116.099979 816.533030 6.142293 116.099979 4799.212454
6 6 4.783847e+05 235.329330 0.002771 142.118045 848.835767 6.135439 142.118045 3404.299119
7 7 5.703618e+05 235.696265 0.002305 170.823773 990.637488 6.117502 170.823773 3295.153254
8 8 7.487164e+05 233.512784 0.001847 204.629545 1227.312216 6.143892 204.629545 3569.631022
9 9 9.565612e+05 233.972350 0.000384 239.124424 1448.331413 6.203149 239.124424 3665.795773
10 10 1.181531e+06 239.460067 0.002496 273.840266 1495.838602 6.280366 273.840266 3933.801920
11 11 1.255305e+06 232.714286 0.000000 307.235081 2311.629295 6.139241 307.235081 3865.355028
12 12 1.536087e+06 233.640625 0.000000 344.975000 3366.306250 6.809375 344.975000 4034.166404
13 13 1.664072e+06 198.243478 0.000000 371.226087 2005.504348 6.600000 371.226087 5845.076115
14 14 5.309983e+06 215.910448 0.000000 385.059701 2074.313433 6.522388 385.059701 10433.259782
15 15 6.035835e+06 228.381818 0.000000 416.436364 2523.854545 6.018182 416.436364 10688.665512
16 16 8.545069e+06 222.041667 0.000000 544.041667 7614.750000 6.916667 544.041667 11393.996187
17 17 6.810475e+05 190.000000 0.000000 414.300000 2832.800000 4.200000 414.300000 1905.551882
18 18 6.351200e+05 329.647059 0.000000 449.352941 6865.470588 7.882353 449.352941 1340.333496
19 19 4.982518e+05 140.888889 0.000000 378.222222 3156.333333 5.222222 378.222222 1646.286622
20 20 2.831429e+06 118.428571 0.000000 746.142857 9822.285714 5.000000 746.142857 3326.955532
21 21 1.400000e+06 477.500000 0.000000 412.500000 984.000000 8.500000 412.500000 3513.772020
22 22 2.866340e+06 141.400000 0.000000 463.800000 2068.000000 6.600000 463.800000 5421.382270
23 23 4.800667e+05 215.666667 0.000000 95.333333 365.000000 5.666667 95.333333 4849.146041
24 24 3.939625e+05 275.875000 0.000000 112.000000 499.125000 4.000000 112.000000 3711.858437
25 25 1.794500e+05 252.200000 0.000000 76.400000 367.600000 6.400000 76.400000 2716.551214
26 26 3.136750e+05 285.250000 0.000000 170.500000 850.250000 4.750000 170.500000 1861.630499
27 27 7.400000e+05 2.000000 0.000000 67.000000 1696.000000 3.000000 67.000000 11044.776119
28 28 2.480000e+05 235.500000 0.000000 120.000000 1360.000000 1.250000 120.000000 1811.904762
29 31 4.282375e+05 239.000000 0.000000 137.750000 303.500000 6.750000 137.750000 3263.877730
30 32 2.106500e+05 143.500000 0.000000 70.000000 383.500000 9.000000 70.000000 3228.125000
31 33 1.784000e+05 303.600000 0.000000 99.000000 411.400000 7.000000 99.000000 1700.643521
32 34 3.000000e+05 34.000000 0.000000 89.000000 811.000000 5.000000 89.000000 3370.786517
33 37 1.050000e+05 119.000000 0.000000 36.000000 92.000000 4.000000 36.000000 2916.666667
34 49 4.140000e+05 123.000000 0.000000 144.000000 506.500000 8.000000 144.000000 2875.000000
35 55 2.650000e+05 330.000000 0.000000 142.000000 691.000000 9.000000 142.000000 1866.197183
36 62 2.100000e+05 405.000000 0.000000 73.000000 103.000000 1.000000 73.000000 2876.712329
37 80 7.750000e+05 44.000000 0.000000 171.000000 935.000000 10.000000 171.000000 4532.163743
In [36]:
df_nb_piece.plot.scatter(x="Nombre pieces principales",y="Surface terrain",marker='+')
C:\Users\Joyce\anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py:1114: UserWarning:

No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored

Out[36]:
<AxesSubplot: xlabel='Nombre pieces principales', ylabel='Surface terrain'>

On observe une relation de linéarité entre la surface terrain et le nombre de pièces principales jusqu'à environ 20 pièces, après quoi la surface terrain n'augmente plus.

Conclusion générale¶

Globalement, les prix ont augmenté notamment accentués par la crise du Covid et, plus récemment, la guerre en Ukraine. Après les nombreux confinements, beaucoup de citadins ont acheté en zone rurale, après avoir ressenti l'étroitesse de la vie citadine.